package ch.epfl.lara.pm.analyze.set;

import ch.epfl.lara.pm.global.ClassTable
import ch.epfl.lara.pm.global.ObjectTable
import ch.epfl.lara.pm.util.MyImplicitConversions

object RefineIPatterns extends MyImplicitConversions{

  def apply(map: PatternMap, ipatterns: List[IPatternDef], tpePats: String): List[IPatternRefinedDef] = {
    map.existsMetasetOrUpdate("",tpePats)
    ipatterns.map(analyze(_,None,map))
  }
  
  def apply(map: PatternMap, ipatterns: List[IPatternDef]): List[IPatternRefinedDef] = 
    ipatterns.map(analyze(_,None,map))
  
  
  private def analyze(ipattern: IPatternRefinedDef, fieldconstr: Option[String],map: PatternMap): IPatternRefinedDef = ipattern match {
    case IVarPattern(tpe,path) if tpe.isPredefinedType || fieldconstr == Some(tpe) || tpe.toString == ClassTable.root =>
      IWildcardPattern
    
    case ivar @ IVarPattern(tpe,path) =>
      val klass = ClassTable.lookupClass(tpe)
      if(klass.isRoot)
        return IWildcardPattern
      else {
        map.existsMetasetOrUpdate(path,klass.name)  
        ivar
      }


    case IClassPattern(objname,ifields,path) => 
      map.existsMetasetOrUpdate(path,fieldconstr.getOrElse(ClassTable.lookupClass(ObjectTable.getExtractorType(objname)).getRootName))
      IClassPattern(objname,ifields.map(ifield => analyze(ifield,None,map)),path)

    case IPatternRefined(subpat,refinement) => subpat.getType match {
      case None => IWildcardPattern //should never be here
      case Some(tpe) => analyze(subpat, Some(refinement),map)
    }

    case jolly @ IWildcardPattern => jolly
  }
}
